<?php

class searchResultsActions extends myFrontendAction{

	public function preExecute(){
		$this->helper = new SearchResultsHelper();
	}
	
	public function executeAjax(sfWebRequest $request){
 		$this->setLayout(false);

		$this->keyword = $this->getKeyword();
		
		$q = Doctrine::getTable('Product')
									->createQuery('ids')
									->select("vp.*, t2.*") // hack to preserve order
									->from('Product vp')
									->leftJoin('vp.Translation t2 WITH t2.lang = ?' , array( $this->getUser()->getCulture() ))
									->leftJoin('vp.ProductGroups pgs')
									->leftJoin('pgs.ProductGroup pg')
									->where('t2.name LIKE ?', $this->getKeyword() . "%")
									->limit(3);

		$this->products = $q->execute();
	}
	
	
	public function executeDetailed(sfWebRequest $request){
		$this->setLayout('layout_widgets_off');

		# validating input
		if( !$this->getKeyword() ) $this->redirect($request->getReferer());

		# find products
		$hits = ProductTable::getLuceneIndex()->find($this->prepareLuceneQuery($this->getKeyword())); // searching the index
		$this->products = $this->getSearchResultsQuery($hits, 20)->execute();

		# find news
		$hits = NewItemTable::getLuceneIndex()->find($this->prepareLuceneQuery($this->getKeyword())); // searching the index
		$this->news = $this->getNewsSearchResultsQuery($hits, 20)->execute();

		# find structure
		$hits = StructureTable::getLuceneIndex()->find($this->prepareLuceneQuery($this->getKeyword())); // searching the index
		$this->nodes = $this->getStructureSearchResultsQuery($hits, 20)->execute();

  		# variables for view
  		$this->keyword = $this->getKeyword();

	}
	
	
	protected function prepareLuceneQuery($keyword){
		
		$keyword = strtolower($keyword);
		
		$query = new Zend_Search_Lucene_Search_Query_Boolean();

		# multiterm query
		$subquery1 = new Zend_Search_Lucene_Search_Query_MultiTerm();
		foreach( explode(' ', $keyword) as $key ){
			
			if(!trim($key)) continue;
			$subquery1->addTerm(new Zend_Search_Lucene_Index_Term($key));

		}
		
		# wildcard query
		Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength(1);
		$tokens = preg_split('/ /', $keyword, -1, PREG_SPLIT_NO_EMPTY);
		$lastWord = trim(array_pop($tokens) ) . "*";
		
		$pattern = new Zend_Search_Lucene_Index_Term($lastWord);
		$subquery2 = new Zend_Search_Lucene_Search_Query_Wildcard($pattern);
		
		
		
		$query->addSubquery($subquery1);
		$query->addSubquery($subquery2);
		
		return $query;
	}


	protected function getNewsSearchResultsQuery($hits, $limit){
		$ids = array(-1); // defeat Doctrine bug
		foreach( $hits as $hit ){
			$ids[] = $hit->pk;
		}


		$idsStr = implode(',', $ids); // ordered search result IDS -> "5,2,4,13,1"

		$q = Doctrine::getTable('NewItem')
									->createQuery('ids')
									->select("ni.*, FIELD(ni.id, {$idsStr} ) AS field") // hack to preserve order
									->from('NewItem ni')
									->whereIn('id', $ids)
									->orderBy('field')
									->limit($limit);

		NewItemTable::commonActivityConstraints($q);

		return $q;
	}


	protected function getStructureSearchResultsQuery($hits, $limit){
		$ids = array(-1); // defeat Doctrine bug
		foreach( $hits as $hit ){
			$ids[] = $hit->pk;
		}


		$idsStr = implode(',', $ids); // ordered search result IDS -> "5,2,4,13,1"

		$q = Doctrine::getTable('Structure')
									->createQuery('ids')
									->select("s.*, FIELD(s.id, {$idsStr} ) AS field") // hack to preserve order
									->from('Structure s')
									->leftJoin('s.PublicUserGroups pug')
									->whereIn('id', $ids)
									->andWhere('pug.structure_id IS NULL')
									->orderBy('field')
									->limit($limit);

		StructureTable::commonActivityConstraints($q);

		return $q;
	}

	/* build DQL */
	protected function getSearchResultsQuery( $hits, $limit ){
		
		
		$ids = array(-1); // defeat Doctrine bug
		foreach( $hits as $hit ){
			$ids[] = $hit->pk;
		}

		
		$idsStr = implode(',', $ids); // ordered search result IDS -> "5,2,4,13,1"

		$q = Doctrine::getTable('Product')
									->createQuery('ids')
									->select("p.*,t.*,pgs.*,pg.*, FIELD(p.id, {$idsStr} ) AS field") // hack to preserve order
									->from('Product p')
									->leftJoin('p.ProductGroups pgs')
									->leftJoin('pgs.ProductGroup pg')
									->whereIn('id', $ids)
									->orderBy('field')
									->limit($limit);

		ProductTable::commonActivityConstraints($q, $this->getUser()->getCulture());
									
		return $q;
	}
	
	/* get keyword from request */
	protected function getKeyword(){
		return (strip_tags( stripslashes( htmlspecialchars( trim( $this->getRequestParameter('search') ) ) ) ) );
	}
	
}